home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- * bitmap -
- * Support for the allocation, manipulation, and display
- * of bitmaps.
- *
- * Paul Haeberli - 1985
- *
- *
- * exports
- *
- Bitmap *bmnew(xsize,ysize)
- void bmfree(b)
- Bitmap *bmclone(b)
- void bmop(b,op)
- void bmclear(b)
- void bmset(b)
- void bmxor(b)
- void bmrand(b)
- void bmpixop(b,x,y,op)
- void bmclrpix(b,x,y)
- void bmsetpix(b,x,y)
- void bmxorpix(b,x,y)
- void bmbmop(dst,x,y,src,op)
- void bmzap(b)
- Bitmap *bmmagnify(b,xmag,ymag)
- Bitmap *bmminimize(b)
- int bmgetpix(b,x,y)
- int bmdomain(b,xmin,ymin,xmax,ymax)
- int bmrasbytes(b)
- Bitmap *bmread(fname)
- Bitmap *bmfromfile(inf)
- void bmwrite(fname,b)
- void bmtofile(outf,b)
- void putbm(port,b)
- Bitmap *getbm(val)
- void bmdrawbig(b,mag)
- void bmbigpix(b,x,y,mag)
- void bmprint(bm)
- *
- */
- #include "gl.h"
- #include "device.h"
- #include "stdio.h"
- #include "port.h"
- #include "bitmap.h"
- #include "obj.h"
- #include "rct.h"
-
- FILE *gfxopen();
-
- #define BMMAGIC 0x5421
-
- static leftmost();
- static rightmost();
-
- static int bittab[16] = {
- 0x8000, 0x4000, 0x2000, 0x1000,
- 0x0800, 0x0400, 0x0200, 0x0100,
- 0x0080, 0x0040, 0x0020, 0x0010,
- 0x0008, 0x0004, 0x0002, 0x0001,
- };
-
- Bitmap *bmnew(xsize,ysize)
- int xsize, ysize;
- {
- Bitmap *b;
-
- b = (Bitmap *)mymalloc(sizeof(Bitmap));
- b->xsize = xsize;
- b->ysize = ysize;
- b->xorig = 0;
- b->yorig = 0;
- b->xmove = 0;
- b->ymove = 0;
- if(b->ysize>0 && b->ysize>0) {
- b->sper = 1+((b->xsize-1)>>4);
- b->base = (short *)mymalloc(bmrasbytes(b));
- bzero(b->base,bmrasbytes(b));
- } else {
- b->sper = 0;
- b->xsize = 0;
- }
- return b;
- }
-
- void bmfree(b)
- Bitmap *b;
- {
- if(b->base)
- free(b->base);
- free(b);
- }
-
- Bitmap *bmclone(b)
- Bitmap *b;
- {
- Bitmap *c;
-
- c = bmnew(b->xsize,b->ysize);
- c->xmove = b->xmove;
- c->ymove = b->ymove;
- c->xorig = b->xorig;
- c->yorig = b->yorig;
- if(b->base)
- bcopy(b->base,c->base,bmrasbytes(b));
- return c;
- }
-
- void bmop(b,op)
- Bitmap *b;
- int op;
- {
- short *sptr;
- int n;
-
- n = b->sper * b->ysize;
- sptr = b->base;
- switch(op) {
- case BM_CLR:
- while(n--)
- *sptr++ = 0;
- break;
- case BM_SET:
- while(n--)
- *sptr++ = 0xffff;
- break;
- case BM_XOR:
- while(n--)
- *sptr++ ^= 0xffff;
- break;
- }
- }
-
- void bmclear(b)
- Bitmap *b;
- {
- bmop(b,BM_CLR);
- }
-
- void bmset(b)
- Bitmap *b;
- {
- bmop(b,BM_SET);
- }
-
- void bmxor(b)
- Bitmap *b;
- {
- bmop(b,BM_XOR);
- }
-
- void bmrand(b)
- Bitmap *b;
- {
- char *cptr;
- short *sptr;
- int n, i;
-
- n = bmrasbytes(b);
- cptr = (char *)b->base;
- i = 0;
- while(n--)
- *cptr++ = rand();
- }
-
- void bmpixop(b,x,y,op)
- Bitmap *b;
- unsigned int x, y;
- int op;
- {
- int offset;
-
- if( (x>=b->xsize) || (y>=b->ysize) ) {
- fprintf(stderr,"bmpixop: range error\n");
- return;
- }
- offset = y*b->sper + (x >> 4);
- switch(op) {
- case BM_CLR:
- b->base[offset] &= ~bittab[x&0xf];
- break;
- case BM_SET:
- b->base[offset] |= bittab[x&0xf];
- break;
- case BM_XOR:
- b->base[offset] ^= bittab[x&0xf];
- break;
- }
- }
-
- void bmclrpix(b,x,y)
- Bitmap *b;
- unsigned int x, y;
- {
- bmpixop(b,x,y,BM_CLR);
- }
-
- void bmsetpix(b,x,y)
- Bitmap *b;
- unsigned int x, y;
- {
- bmpixop(b,x,y,BM_SET);
- }
-
- void bmxorpix(b,x,y)
- Bitmap *b;
- unsigned int x, y;
- {
- bmpixop(b,x,y,BM_XOR);
- }
-
- void bmbmop(dst,x,y,src,op)
- Bitmap *dst, *src;
- unsigned int x, y;
- int op;
- {
- int xmax, doff;
- int srcymin, srcymax;
- int xsrc, ysrc, ydst;
- unsigned short *sptr;
- unsigned short *dptr;
- rct srct, drct, irct;
-
- srct.xmin = 0;
- srct.ymin = 0;
- srct.xmax = 0+src->xsize;
- srct.ymax = 0+src->ysize;
- drct.xmin = -x;
- drct.ymin = -y;
- drct.xmax = dst->xsize-x;
- drct.ymax = dst->ysize-y;
- if(!rctinter(&srct,&drct,&irct))
- return;
-
- srcymin = irct.ymin;
- srcymax = irct.ymax;
- xmax = src->xsize;
- for(ysrc=srcymin; ysrc<srcymax; ysrc++) {
- ydst = ysrc+y;
- sptr = (unsigned short *)(src->base+(ysrc*src->sper));
- dptr = (unsigned short *)(dst->base+((ydst*dst->sper)+(x>>4)));
- doff = x&0xf;
- if(doff == 0) {
- switch(op) {
- case BM_CLR:
- for(xsrc=0; xsrc<xmax; xsrc+=16)
- *dptr++ &= ~(*sptr++);
- break;
- case BM_SET:
- for(xsrc=0; xsrc<xmax; xsrc+=16)
- *dptr++ |= *sptr++;
- break;
- case BM_XOR:
- for(xsrc=0; xsrc<xmax; xsrc+=16)
- *dptr++ ^= *sptr++;
- break;
- }
- } else {
- for(xsrc=0; xsrc<xmax; xsrc+=16) {
- switch(op) {
- case BM_CLR:
- *dptr &= ~(*sptr>>doff);
- dptr++;
- *dptr &= ~(*sptr<<(16-doff));
- sptr++;
- break;
- case BM_SET:
- *dptr |= *sptr>>doff;
- dptr++;
- *dptr |= *sptr<<(16-doff);
- sptr++;
- break;
- case BM_XOR:
- *dptr ^= *sptr>>doff;
- dptr++;
- *dptr ^= *sptr<<(16-doff);
- sptr++;
- break;
- }
- }
- }
- }
- }
-
- void bmzap(b)
- Bitmap *b;
- {
- b->xmove = 0;
- b->ymove = 0;
- b->xorig = 0;
- b->yorig = 0;
- }
-
- Bitmap *bmmagnify(b,xmag,ymag)
- Bitmap *b;
- int xmag, ymag;
- {
- Bitmap *c;
- short *sptr;
- int word;
- int x, y;
- int m;
- int xpos, rowstart;
- int offset;
-
- c = bmnew(xmag*b->xsize,ymag*b->ysize);
- c->xmove = xmag*b->xmove;
- c->ymove = ymag*b->ymove;
- c->xorig = xmag*b->xorig;
- c->yorig = ymag*b->yorig;
- sptr = c->base;
- rowstart = ymag*y*c->sper;
- for(y=0; y<b->ysize; y++) {
- xpos = 0;
- for(x=0; x<b->xsize; x++) {
- if(bmgetpix(b,x,y)) {
- for(m=0; m<xmag; m++) {
- offset = rowstart + ((xpos) >> 4);
- word = sptr[offset];
- word |= bittab[xpos&0xf];
- sptr[offset] = word;
- xpos++;
- }
- } else
- xpos += xmag;
- }
- for(m=0; m<(ymag-1); m++) {
- bcopy(sptr+rowstart,sptr+rowstart+c->sper,c->sper<<1);
- rowstart += c->sper;
- }
- rowstart += c->sper;
- }
- return c;
- }
-
- Bitmap *bmminimize(b)
- Bitmap *b;
- {
- Bitmap *c;
- int x, y;
- int xsize, ysize;
- int xmin, ymin, xmax, ymax;
-
- if(bmdomain(b,&xmin,&ymin,&xmax,&ymax)) {
- xsize = xmax-xmin+1;
- ysize = ymax-ymin+1;
- c = bmnew(xsize,ysize);
- for(y=0; y<ysize; y++)
- for(x=0; x<xsize; x++) {
- if(bmgetpix(b,x+xmin,y+ymin))
- bmsetpix(c,x,y);
- }
- c->xorig = b->xorig-xmin;
- c->yorig = b->yorig-ymin;
- } else {
- c = bmnew(1,1);
- }
- c->xmove = b->xmove;
- c->ymove = b->ymove;
- return c;
- }
-
- int bmgetpix(b,x,y)
- Bitmap *b;
- unsigned int x, y;
- {
- int offset;
-
- if( (x>=b->xsize) || (y>=b->ysize) ) {
- fprintf(stderr,"bmgetpix: range error\n");
- return 0;
- }
- offset = y*b->sper + (x >> 4);
- if(b->base[offset] & bittab[x&0xf])
- return 1;
- else
- return 0;
- }
-
- int bmdomain(b,xmin,ymin,xmax,ymax)
- Bitmap *b;
- int *xmin, *ymin, *xmax, *ymax;
- {
- int x, y;
- int ixmin, ixmax;
- int iymin, iymax;
- short *sptr;
- int xoffset;
- int temp;
- short excessmask;
-
- sptr = b->base;
- iymin = 100000;
- iymax = -100000;
- ixmin = 100000;
- ixmax = -100000;
- excessmask = 0xffff<<(15-((b->xsize-1)&0xf));
- for(y=0; y<b->ysize; y++) {
- xoffset = 0;
- for(x=0; x<b->sper; x++) {
- if(x == (b->sper-1))
- *sptr &= excessmask;
- if(*sptr) {
- temp = xoffset + leftmost(*sptr);
- if(temp<ixmin)
- ixmin = temp;
- temp = xoffset + rightmost(*sptr);
- if(temp>ixmax)
- ixmax = temp;
- if(y<iymin)
- iymin = y;
- if(y>iymax)
- iymax = y;
- }
- sptr++;
- xoffset += 16;
- }
- }
- if(iymin>iymax) {
- *xmin = 0;
- *xmax = 0;
- *ymin = 0;
- *ymax = 0;
- return 0;
- } else {
- *xmin = ixmin;
- *xmax = ixmax;
- *ymin = iymin;
- *ymax = iymax;
- return 1;
- }
- }
-
- static leftmost(val)
- short val;
- {
- int i;
- int bit;
-
- bit = 0x8000;
- for(i=0; i<16; i++) {
- if(bit&val)
- return i;
- bit >>= 1;
- }
- return 0;
- }
-
- static rightmost(val)
- short val;
- {
- int i;
- int bit;
-
- bit = 0x1;
- for(i=16; i--;) {
- if(bit&val)
- return i;
- bit <<= 1;
- }
- return 0;
- }
-
- int bmrasbytes(b)
- Bitmap *b;
- {
- return b->ysize*2*b->sper;
- }
-
- Bitmap *bmread(fname)
- char *fname;
- {
- FILE *inf;
- Bitmap *b;
-
- inf = gfxopen(fname,"r");
- if(!inf) {
- fprintf(stderr,"bmread: can't open input file [%s]\n",fname);
- exit(1);
- }
- b = bmfromfile(inf);
- fclose(inf);
- return b;
- }
-
- Bitmap *bmfromfile(inf)
- FILE *inf;
- {
- Bitmap *b;
- long magic[2];
-
- fread(magic,2*sizeof(long),1,inf);
- if(magic[0] != BMMAGIC || magic[1] != BMMAGIC) {
- fprintf(stderr,"bad magic number in bit map header\n");
- return 0;
- }
- b = (Bitmap *)mymalloc(sizeof(Bitmap));
- fread(&b->base,sizeof(short *),1,inf);
- fread(&b->xsize,sizeof(short),1,inf);
- fread(&b->ysize,sizeof(short),1,inf);
- fread(&b->xorig,sizeof(short),1,inf);
- fread(&b->yorig,sizeof(short),1,inf);
- fread(&b->xmove,sizeof(short),1,inf);
- fread(&b->ymove,sizeof(short),1,inf);
- fread(&b->sper,sizeof(short),1,inf);
- b->base = (short *)mymalloc(bmrasbytes(b));
- fread(b->base,bmrasbytes(b),1,inf);
- return b;
- }
-
- void bmtofile(outf,b)
- FILE *outf;
- Bitmap *b;
- {
- long magic[2];
-
- magic[0] = BMMAGIC;
- magic[1] = BMMAGIC;
- fwrite(magic,2*sizeof(long),1,outf);
- fwrite(&b->base,sizeof(short *),1,outf);
- fwrite(&b->xsize,sizeof(short),1,outf);
- fwrite(&b->ysize,sizeof(short),1,outf);
- fwrite(&b->xorig,sizeof(short),1,outf);
- fwrite(&b->yorig,sizeof(short),1,outf);
- fwrite(&b->xmove,sizeof(short),1,outf);
- fwrite(&b->ymove,sizeof(short),1,outf);
- fwrite(&b->sper,sizeof(short),1,outf);
- fwrite(b->base,bmrasbytes(b),1,outf);
- }
-
- void bmwrite(fname,b)
- char *fname;
- Bitmap *b;
- {
- FILE *outf;
-
- outf = gfxopen(fname,"w");
- if(!outf) {
- fprintf(stderr,"bmwrite: can't open output file [%s]\n",fname);
- exit(1);
- }
- bmtofile(outf,b);
- fclose(outf);
- }
-
- void bmdrawbig(b,mag)
- Bitmap *b;
- int mag;
- {
- int x, y;
- int bx, by;
- int cdark, cbright;
-
- by = 0;
- cdark = grey(0.1);
- cbright = grey(0.9);
- for(y=0; y<b->ysize; y++) {
- bx = 0;
- for(x=0; x<b->xsize; x++) {
- if(bmgetpix(b,x,y))
- usecolor(cdark);
- else
- usecolor(cbright);
- fillrecti(bx,by,bx+(mag-2),by+(mag-2));
- if(x == b->xorig && y == b->yorig) {
- rgb(1.0,0.0,0.0);
- recti(bx,by,bx+(mag-2),by+(mag-2));
- }
- bx += mag;
-
- }
- by += mag;
- }
- }
-
- void bmbigpix(b,x,y,mag)
- Bitmap *b;
- int x, y;
- int mag;
- {
- int bx, by;
-
- if(bmgetpix(b,x,y))
- grey(0.1);
- else
- grey(0.9);
- bx = x*mag;
- by = y*mag;
- fillrecti(bx,by,bx+(mag-2),by+(mag-2));
- if(x == b->xorig && y == b->yorig) {
- rgb(1.0,0.0,0.0);
- recti(bx,by,bx+(mag-2),by+(mag-2));
- }
- }
-
- void bmprint(bm)
- Bitmap *bm;
- {
- printf("Bitmap size %d by %d\n",bm->xsize,bm->ysize);
- printf("Bitmap orig %d by %d\n",bm->xorig,bm->yorig);
- printf("Bitmap move %d by %d\n",bm->xmove,bm->ymove);
- printf("Bitmap sper %d\n",bm->sper);
- printf("Bitmap data %x\n",bm->base);
- }
-